package com.abcgroup.hyppo.tools;

import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.hibernate.Query;
import com.abcgroup.hyppo.jdbc.IConnectionProvider;
import com.abcgroup.hyppo.loader.IHibernateLoader;

import java.sql.SQLException;
import java.sql.Connection;
import java.util.Map;

public class SimpleHQLExecutor implements IHQLExecutor {

    SessionFactory sf;

    IConnectionProvider cp;

    Session activeSession = null;

    Connection activeConnection = null;

    protected Session openSession() throws SQLException {
        synchronized(this) {
            if (activeSession != null) {
                throw new IllegalStateException("Already has opened session!");
            }
            if (activeConnection == null) {
                activeConnection = cp.getConnection();
            }
            return sf.openSession(activeConnection);
        }
    }

    protected void closeSession() throws SQLException {
        synchronized(this) {
            if (activeSession != null) {
                activeSession.close();
                activeSession = null;
            }
        }
    }

    public SimpleHQLExecutor(IConnectionProvider cp, IHibernateLoader hl) {
        this.sf = hl.getHibernateConfiguration().buildSessionFactory();
        this.cp = cp;
    }

    public SimpleHQLExecutor(SessionFactory sf, IConnectionProvider cp) {
        this.sf = sf;
        this.cp = cp;
    }

    public Object executeHQL(String hql) throws SQLException {
        try {
            Session session = openSession();
            return session.createQuery(hql).list();
        } finally {
            closeSession();
        }
    }

    public Object executeNamedHQL(String hqlName) throws SQLException {
        try {
            Session session = openSession();
            return session.getNamedQuery(hqlName).list();
        } finally {
            closeSession();
        }
    }

    public Object executeHQL(String hql, Map<String, Object> params) throws SQLException {
        try {
            Session session = openSession();
            Query query = session.getNamedQuery(hql);
            for (String s : params.keySet()) {
                query.setParameter(s, params.get(s));
            }
            return query.list();
        } finally {
            closeSession();
        }
    }
}
